﻿using Common;
using Entities;
using Entities.Admin;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AdminModels
{
    public static class Settings
    {
        /// <summary>
        /// Gets a setting from the DB, attempts to parse
        /// to an bool
        /// </summary>
        /// <param name="name">Name of the Setting</param>
        /// <param name="defaultValue">Return on Fail, default false</param>
        /// <returns>Setting Value, or defaultValue</returns>
        public static bool GetSetting(string name, bool defaultValue = false)
        {
            bool retVal;

            using (AegirContext db = new AegirContext())
            {
                List<SettingsEntity> settingList = db.Settings.Where(s => s.setting == name).ToList<SettingsEntity>();

                if (settingList.Count > 0)
                {
                    bool suceeded = bool.TryParse(settingList.First().value, out retVal);

                    if (!suceeded)
                    {
                        retVal = defaultValue;
                    }
                }
                else
                {
                    retVal = defaultValue;
                }
            }

            return retVal;
        }

        /// <summary>
        /// Gets a setting from the DB, attempts to parse
        /// to an int
        /// </summary>
        /// <param name="name">Name of the Setting</param>
        /// <param name="defaultValue">Return on Fail, default 0</param>
        /// <returns>Setting Value, or defaultValue</returns>
        public static int GetSetting(string name, int defaultValue = 0)
        {
            int retVal;

            using (AegirContext db = new AegirContext())
            {
                List<SettingsEntity> settingList = db.Settings.Where(s => s.setting == name).ToList<SettingsEntity>();

                if (settingList.Count > 0)
                {
                    bool suceeded = int.TryParse(settingList.First().value, out retVal);

                    if (!suceeded)
                    {
                        retVal = defaultValue;
                    }
                }
                else
                {
                    retVal = defaultValue;
                }
            }

            return retVal;
        }

        /// <summary>
        /// Gets a setting from the DB, attempts to parse
        /// to a double
        /// </summary>
        /// <param name="name">Name of the Setting</param>
        /// <param name="defaultValue">Return on Fail, default 0</param>
        /// <returns>Setting Value, or defaultValue</returns>
        public static double GetSetting(string name, double defaultValue = 0)
        {
            double retVal;

            using (AegirContext db = new AegirContext())
            {
                List<SettingsEntity> settingList = db.Settings.Where(s => s.setting == name).ToList<SettingsEntity>();

                if (settingList.Count > 0)
                {
                    bool suceeded = double.TryParse(settingList.First().value, out retVal);

                    if (!suceeded)
                    {
                        retVal = defaultValue;
                    }
                }
                else
                {
                    retVal = defaultValue;
                }
            }

            return retVal;
        }

        /// <summary>
        /// Gets a setting from the DB, return a string
        /// </summary>
        /// <param name="name">Name of the Setting</param>
        /// <param name="defaultValue">Return on Fail, default null</param>
        /// <returns>Setting Value, or defaultValue</returns>
        public static string GetSetting(string name, string defaultValue = null)
        {
            string retVal;

            using (AegirContext db = new AegirContext())
            {
                List<SettingsEntity> settingList = db.Settings.Where(s => s.setting == name).ToList<SettingsEntity>();

                if (settingList.Count > 0)
                {
                    retVal = settingList.First().value;
                }
                else
                {
                    retVal = defaultValue;
                }
            }

            return retVal;
        }

        /// <summary>
        /// Gets a JSON encoded setting from the DB, attempts to parse
        /// to an int
        /// </summary>
        /// <typeparam name="T">JSON Mappable Setting Type</typeparam>
        /// <param name="name">Name of the Setting</param>
        /// <param name="defaultValue">Return on Fail, default null</param>
        /// <returns>Setting Value, or defaultValue</returns>
        public static T? GetSetting<T>(string name, T? defaultValue = null)
            where T : struct
        {
            T? retVal;
            string rawData = "";

            using (AegirContext db = new AegirContext())
            {
                List<SettingsEntity> settingList = db.Settings.Where(s => s.setting == name).ToList<SettingsEntity>();

                if (settingList.Count > 0)
                {
                    rawData = settingList.First().value;
                }
            }

            if (!string.IsNullOrWhiteSpace(rawData))
            {
                // Deserialize the JSON
                JsonSerializerSettings settings = DefaultValues.GetJsonSettings();
                try
                {
                    retVal = JsonConvert.DeserializeObject<T>(rawData, settings);
                }
                catch
                {
                    retVal = defaultValue;
                }
            }
            else
            {
                retVal = defaultValue;
            }

            return retVal;
        }
    }
}
